#include"field.h"
#include<stdio.h>
#include<stdlib.h>

int sign(int val){
	if(val > 0) return 1;
	if(val < 0) return -1;
	return 0;
}

Field::Field(): num_of_figurs(32), q_move(false){	
//	figurs[0] = new Rook(true, 0, 4);
	for(int i = 0; i < 8; ++i){	figurs[i] = new Pawn(true,i,1);}
	for(int i = 8; i < 16; ++i){ figurs[i] = new Pawn(false, i-8,6);}
	figurs[16] = new Rook(true, 0, 0);
	figurs[17] = new Rook(true, 7, 0);
	figurs[18] = new Rook(false, 7, 7);
	figurs[19] = new Rook(false, 0, 7);
	figurs[20] = new Knight(true, 1, 0);
	figurs[21] = new Knight(true, 6, 0);
	figurs[22] = new Knight(false, 1, 7);
	figurs[23] = new Knight(false, 6, 7);
	figurs[24] = new Bishop(true, 2, 0);
	figurs[25] = new Bishop(true, 5, 0);
	figurs[26] = new Bishop(false, 2, 7);
	figurs[27] = new Bishop(false, 5, 7);
	figurs[28] = new King(true, 4, 0);
	figurs[29] = new King(false, 4, 7);
	figurs[30] = new Queen(true, 3, 0);
	figurs[31] = new Queen(false, 3, 7);
};

bool Field::move(pos from, pos to){
	Figure *cur = NULL;
	int killed_fid = -1, cur_id = -1;
	for(int i = 0; i < num_of_figurs; ++i){
		Figure* tmp = figurs[i];
		if(tmp->get_position() == from) {cur = tmp; cur_id = i;};
		if(tmp->get_position() == to) killed_fid = i;
	}	
	
	if(cur == NULL) return false;

	if(q_move != cur->get_color()) return false;

	if(cur->move(to)){
		printf("Figure can move like this\n");
		if(is_barrier_not_exist(cur, to)){
			printf("No barier for figure\n");
			cur->inc();
			if(killed_fid >= 0){ kill_figure(killed_fid); }
			if((cur->get_letter() == 'p' || cur->get_letter() == 'P') && (to.y == 7 || to.y == 0)){
				bool tmp_col = cur->get_color();
				delete cur;
				figurs[cur_id] = new Queen(tmp_col, to.x, to.y);
			}else{
				cur->set_position(to.x,to.y);
			}
			q_move = !q_move;
			return true;
		}
	}

	return false;
}

void Field::draw() const{
	char field[8][10];

	for(int i = 0; i < 8; ++i){
			field[i][0] = i+49;
			field[i][1] = ' ';
		for(int j = 2; j < 10; ++j)
			field[i][j] = ((i+j)%2 == 0)? '*': ' ';
	}

	for(int i = 0; i < num_of_figurs; ++i){
		Figure* tmp = figurs[i];
		field[tmp->get_y()][tmp->get_x() + 2] = tmp->get_letter();
	}

	for(int i = 0; i < 8; ++i){
		for(int j = 0; j < 10; ++j){
			printf("%c", field[i][j]);
		}
		printf("\n");
	}
		printf("  abcdefgh\n\n");
};


bool Field::is_barrier_not_exist(Figure* cur, const pos& to) const{
	int field[8][8];
	int i,j;

	for(i = 0; i < 8; ++i)
		for(j = 0; j < 8; ++j)
			field[i][j] = 0;

	for(i = 0; i < num_of_figurs; ++i){
		Figure* tmp = figurs[i];
		field[tmp->get_y()][tmp->get_x()] = (tmp->get_color() == true)? 2 : 1;
	}

	pos from = cur->get_position();
	int color = cur->get_color();

	int x_div = sign(to.x - from.x);
	int y_div = sign(to.y - from.y);

	if(field[to.y][to.x] == color + 1) return false;
	
	char c = cur->get_letter();
	if(c == 'q' || c == 'Q') c = (x_div == 0 || y_div == 0)? 'r' : 'b';

	switch(c){
		case 'P':
		case 'p':
			if(x_div == 0){
				for(i = from.y + y_div; i != to.y; i+=y_div)
					if(field[i][to.x] != 0) return false;
				if(field[to.y][to.x] != 0) return false;
			}else{
				if(field[to.y][to.x] == 0) return false;
			}
			break;

		case 'r':
		case 'R':	
			if(x_div == 0){
				for(i = from.y + y_div; i != to.y; i += y_div)
					if(field[i][from.x] != 0) return false;
				}else{
					for(i = from.x + x_div; i != to.x; i += x_div)
						if(field[from.y][i] != 0) return false;
				}
			break;

		case 'b':
		case 'B':
			for(i = from.x + x_div, j = from.y + y_div; i!=to.x; i+= x_div, j+=y_div){
				if(field[j][i] != 0) return false;
			}
			break;
	}
	return true;
}

bool Field::is_check(bool color) const{	
	pos King_pos;
	int i;
	
	int field[10][10];
	for(i = 0; i < 10; ++i)
		for(int j = 0; j < 10; ++j)
			field[i][j] = 0;

	for(i = 0; i < num_of_figurs; ++i){
		Figure* tmp = figurs[i];
		char c = tmp->get_letter();
		field[tmp->get_y()+1][tmp->get_x()+1] = c;
		if((color && c == 'k') || (!color && c=='K')){
			King_pos = tmp->get_position();
			King_pos.x++; King_pos.y++;
		}
	}

	////////////////
	// Pawn check //
	////////////////
	if(color){
		if(field[King_pos.y+1][King_pos.x+1] == 'P' || field[King_pos.y+1][King_pos.x-1] == 'P')
			return true;
	}else{
		if(field[King_pos.y-1][King_pos.x+1] == 'p' || field[King_pos.y-1][King_pos.x-1] == 'p')
			return true;
	}

	////////////////
	// Rook check //
	////////////////

	for(i = King_pos.y+1; i < 9; ++i){
		if(field[i][King_pos.x] == 'r'- 32*(color)) return true;
		if(field[i][King_pos.x] != 0) break;
	}
	for(i = King_pos.y-1; i > 0; --i){
		if(field[i][King_pos.x] == 'r' - 32*(color)) return true;
		if(field[i][King_pos.x] != 0) break;
	}
	for(i = King_pos.x+1; i < 9; ++i){
		if(field[King_pos.y][i] == 'r'- 32*(color)) return true;
//		printf("%c\n",field[King_pos.y][i]);
//		printf("i = %d\n",i);
		if(field[King_pos.y][i] != 0) break;
	}
	for(i = King_pos.x-1; i > 0; --i){
		if(field[King_pos.y][i] == 'r' - 32*(color)) return true;
		if(field[King_pos.y][i] != 0) break;
	}

		//////////////////
		// Bishop Check //
		//////////////////
	
		int y=King_pos.y;
        for(i=King_pos.x-1; i>0;i--)
		{
			y--;
			if(field[y][i]=='b'-32*(color)) return true;
			if(field[y][i] != 0) break;
		}
		y=King_pos.y;
        for(i=King_pos.x+1; i<9;i++)
		{
			y--;
			if(field[King_pos.y][i]=='b'-32*(color)) return true;
			if(field[King_pos.y][i] != 0) break;
		}
		y=King_pos.y;
        for(i=King_pos.x+1; i<9;i++)
		{
			y++;
			if(field[y][i]=='b'-32*(color)) return true;
			if(field[y][i] != 0) break;
		}
		y=King_pos.y;
        for(i=King_pos.x-1; i>0;i--)
		{
			y++;
			if(field[King_pos.y][i]=='b'-32*(color)) return true;
			if(field[King_pos.y][i] != 0) break;
		}
		y=King_pos.y;
        printf("frerverfgrf\n");
    
		    //////////////////
        // Knight Check //
        //////////////////
	if((field[King_pos.y-2][King_pos.x-1]=='n'-32*(color))||
			(field[King_pos.y-2][King_pos.x+1]=='n'-32*(color))||
			(field[King_pos.y+2][King_pos.x-1]=='n'-32*(color))||
			(field[King_pos.y+2][King_pos.x+1]=='n'-32*(color))||
			(field[King_pos.y-1][King_pos.x-2]=='n'-32*(color))||
			(field[King_pos.y+1][King_pos.x-2]=='n'-32*(color))||
			(field[King_pos.y-1][King_pos.x+2]=='n'-32*(color))||
			(field[King_pos.y+1][King_pos.x+2]=='n'-32*(color)))
		{
			printf("Shah!!\n");
			return true;
		}
        

		/////////////////	
		//  King Check //
    /////////////////

	for(i=King_pos.x-1;i<=King_pos.x+1;i++)
	{
		if(field[King_pos.y+1][i]=='k'-32*(color)) return true;
		if(field[King_pos.y-1][i]=='k'-32*(color)) return true;
	}

	if((field[King_pos.y][King_pos.x-1]=='k'-32*(color))||
		(field[King_pos.y][King_pos.x+1]=='k'-32*(color))) return true;
  /* For next move*/

   return false;
};

bool Field::kill_figure(int number){
	if(number < num_of_figurs){
		delete figurs[number];
		figurs[number] = figurs[--num_of_figurs];
		return true;
	}
	return false;
}

Field::~Field(){
	for(int i = 0; i <num_of_figurs; ++i){
		delete figurs[i];
	}
};
